'''
Created on Feb 29, 2012

@author: Johnathon
'''
#from LineValues import X, One, Zero, D, DNot
from LineValues import Zero, X, One, D, DNot

VALUES = (Zero, X, One, D, DNot)

lineVals = (Zero, One, D, DNot, X)


def invertSignal(signal):
    if signal not in VALUES:
        raise AttributeError("Invalid input for inversion")
    
    if signal is Zero:
        return One
            
    elif signal is One:
        return Zero
            
    elif signal is D:
        return DNot
                
    elif signal is DNot:
        return D
            
    elif signal is X:
        return X
  
def printListOfLineValues(l):  
    string = "["
    for vals in l:
        if isinstance(vals, list):
            string += printListOfLineValues(vals)
        else:
            string += vals.__str__() + ','
    string = string[:-1]
    string += "]\n"
    return string
    
def collapseFaults(gates, lines):
    allFaults = list()
    collapsedFaults = list()
    for level in lines:
        for line in level: #Generate all allFaults
            allFaults.append((line, Zero))
            allFaults.append((line, One))
    for level in gates: #Generate fault collapses
        for gate in level:
            collapsedFaults.extend(gate.getEquivalentFaults())
            
    #Check each equivalence class and remove the allFaults in it from
    #the global fault list
    mergedFaults = list()
    
    while collapsedFaults:
        faultSet = collapsedFaults.pop()    #Get an equivalence class
        if not faultSet:
            continue
        for fault in faultSet:              #if the fault is in the faultset, remove it
            if fault in allFaults:
                allFaults.remove(fault)
            
            for f in collapsedFaults:       #if the fault is in another equivalence class, merge them
                if fault in f:
                    f.remove(fault)
                    faultSet.extend([x for x in f if x not in faultSet])
        mergedFaults.append(faultSet)
    
    mergedFaults.extend([(x,) for x in allFaults])
    
    
    return mergedFaults
                    
            
            
            
            
            
            
            
            
            
            
            
            
            
            
